//
// Created by wsl on 2024/3/5.
//

#include "BidLinkList.h"

DataStructure_Warning_Unused
static BidLinkList_Node BidLinkList_CreateNode(T e, size_t dataSize) {
// 你的无法访问的代码

	if (NULL == e)
		return NULL;

	//创建节点
	BidLinkList_Node node = (BidLinkList_Node) DataStructure_AllocT(BidLinkList_N);
	if (NULL == node) {

		DataStructure_Overflow_Handler();
		return NULL;
	}

	//创建数据域
	T data = DataStructure_Alloc(dataSize);
	if (NULL == data) {
		DataStructure_MemoryFree(node);

		DataStructure_Overflow_Handler();
		// 你的无法访问的代码
		return NULL;
	}

	//初始化数据域
	DataStructure_MemoryCpy(data, e, dataSize);

	//初始化节点
	node->data = data;
	node->pre = NULL;
	node->next = NULL;

	return node;
}

DataStructure_Warning_Unused
static Status BidLinkList_DeleteNode(BidLinkList_Node node) {
	if (NULL == node)
		return FALSE;

	if (NULL != node->data)
		DataStructure_MemoryFree(node->data);

	DataStructure_MemoryFree(node);

	return TRUE;
}

DataStructure_Warning_Unused
static BidLinkList_Node BidLinkList_findNode(BidLinkList list, int index) {
	if (NULL == list || BidLinkList_isEmpty(list) || index < 1 || index > BidLinkList_length(list))
		return NULL;

	BidLinkList_Node curNode = list->head->next;

	while (curNode != list->head && --index) curNode = curNode->next;

	return curNode;
}

DataStructure_Warning_Unused
int BidLinkList_length(BidLinkList list) {
	if (NULL == list)
		return 0;

	return list->length;
}

DataStructure_Warning_Unused
Status BidLinkList_isEmpty(BidLinkList list) {
	if (NULL == list)
		return FALSE;

	return list->length <= 0 ? TRUE : FALSE;
}

DataStructure_Warning_Unused
BidLinkList BidLinkList_create(size_t dataSize) {
//	//参数合法性检查
//	if(NULL == list)
//		return FALSE;
//
//	if (NULL != *list)
//		BidLinkList_destroy(list);

	//创建实例化对象
	BidLinkList bidLinkList = (BidLinkList) DataStructure_AllocT(BLL);
	if (NULL == bidLinkList) {
		DataStructure_Overflow_Handler();

		return NULL;
	}

	//创建头节点
	BidLinkList_Node headNode = (BidLinkList_Node) DataStructure_AllocT(BidLinkList_N);
	if (NULL == headNode) {
		DataStructure_MemoryFree(bidLinkList);

		DataStructure_Overflow_Handler();

		return NULL;
	}

	//初始化头节点属性
	headNode->data = NULL;
	headNode->pre = headNode;
	headNode->next = headNode;

	//初始化对象属性
	bidLinkList->head = headNode;
	bidLinkList->length = 0;
	bidLinkList->dataSize = dataSize;

	return bidLinkList;
}

DataStructure_Warning_Unused
Status BidLinkList_add(BidLinkList list, T e) {
	if (NULL == list)
		return FALSE;

	//创建节点
	BidLinkList_Node node = BidLinkList_CreateNode(e, list->dataSize);
	if (NULL == node)
		return FALSE;

	//链接到链表中
	if (BidLinkList_isEmpty(list))        //无节点时
	{
		node->next = list->head;
		node->pre = list->head;

		list->head->pre = node;
		list->head->next = node;
	}
	else {
		node->next = list->head;
		node->pre = list->head->pre;

		list->head->pre->next = node;
		list->head->pre = node;
	}

	list->length++;

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_header(BidLinkList list, T e) {
	if (NULL == list)
		return FALSE;

	//创建节点
	BidLinkList_Node node = BidLinkList_CreateNode(e, list->dataSize);
	if (NULL == node)
		return FALSE;

	//链接到链表中
	if (BidLinkList_isEmpty(list))        //无节点时
	{
		node->next = list->head;
		node->pre = list->head;

		list->head->pre = node;
		list->head->next = node;
	}
	else {
		node->next = list->head->next;
		node->pre = list->head->pre;

		list->head->next->pre = node;
		list->head->next = node;
	}

	list->length++;

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_insert(BidLinkList list, T e, int index) {
	if (NULL == list || index < 1)
		return FALSE;

	//链接到链表中
	if (BidLinkList_isEmpty(list) || index == 1)        //无节点时
	{
		BidLinkList_header(list, e);
	}
	else if (index > BidLinkList_length(list)) {
		BidLinkList_add(list, e);
	}
	else {
		//创建节点
		BidLinkList_Node node = BidLinkList_CreateNode(e, list->dataSize);
		if (NULL == node)
			return FALSE;

		//找到对应位置
		BidLinkList_Node curNode = list->head->next;
		while (--index) curNode = curNode->next;

		node->next = curNode;
		node->pre = curNode->pre;

		curNode->pre->next = node;
		curNode->pre = node;

		list->length++;
	}

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_clear(BidLinkList list) {
	if (NULL == list || BidLinkList_isEmpty(list))
		return FALSE;

	BidLinkList_Node curNode = list->head->next;
	BidLinkList_Node temp = NULL;
	while (curNode != list->head) {

		temp = curNode;
		curNode = curNode->next;

		BidLinkList_DeleteNode(temp);
		list->length--;
	}

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_destroy(BidLinkList *list) {
	if (NULL == list || NULL == *list)
		return FALSE;

	if (!BidLinkList_isEmpty(*list))
		//释放所有节点
		BidLinkList_clear(*list);

	//释放头节点
	BidLinkList_DeleteNode((*list)->head);
	//释放对象本身
	DataStructure_MemoryFree(*list);
	//指空
	*list = NULL;

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_replace(BidLinkList list, T e, int index) {
	if (NULL == e || index < 1 || index > BidLinkList_length(list))
		return FALSE;

	BidLinkList_Node node = BidLinkList_findNode(list, index);
	if (NULL == node)
		return FALSE;

	DataStructure_MemoryCpy(node->data, e, list->dataSize);

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_at(BidLinkList list, int index, T buf) {
	BidLinkList_Node tem = BidLinkList_findNode(list, index);
	if (NULL == tem)
		return FALSE;

	DataStructure_MemoryCpy(buf, tem->data, list->dataSize);

	return TRUE;
}

DataStructure_Warning_Unused
int BidLinkList_equalsFind(BidLinkList list, T e, char (*equals)(T e, T b)) {
	if (NULL == list || NULL == e || BidLinkList_isEmpty(list))
		return 0;

	BidLinkList_Node curNode = list->head->next;
	int i = 1;

	while (curNode != list->head) {
		if (equals(e, curNode->data) == 1) {
			return i;
		}
		i++;
		curNode = curNode->next;
	}

	return 0;
}

DataStructure_Warning_Unused
void BidLinkList_traversal(BidLinkList list, void(*look)(T e)) {
	if (NULL == list || BidLinkList_isEmpty(list)) {
		return;
	}

//	BidLinkList_Node curNode = list->head;
//	do{
//		look(curNode->data);
//
//		curNode = curNode->pre;
//	} while (curNode != list->head);

	BidLinkList_Node curNode = list->head;
	do {
		look(curNode->data);

		curNode = curNode->next;
	} while (curNode != list->head);
}

DataStructure_Warning_Unused
Status BidLinkList_connect(BidLinkList list1, BidLinkList *list2) {
	if (NULL == list1 || NULL == list2 || NULL == *list2 || BidLinkList_isEmpty(list1) || BidLinkList_isEmpty(*list2))
		return FALSE;

	list1->head->pre->next = (*list2)->head->next;

	(*list2)->head->next->pre = list1->head->pre;
	(*list2)->head->pre->next = list1->head;

	list1->head->pre = (*list2)->head->pre;

	list1->length += (*list2)->length;

	DataStructure_MemoryFree((*list2)->head);
	DataStructure_MemoryFree(*list2);

	*list2 = NULL;

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_reverse(BidLinkList list) {
	if (BidLinkList_isEmpty(list) || BidLinkList_length(list) == 1)
		return FALSE;

#if 1
	BidLinkList_Node head = list->head->next;
	BidLinkList_Node end = list->head->pre;
	size_t dataSize = list->dataSize;

	//创造一个临时空间
	T temp = DataStructure_Alloc(dataSize);
	if (NULL == temp) {
		DataStructure_Overflow_Handler();
		return OVERFLOW;
	}

	while (1) {
		if (head == end || head->pre == end || end->next == head)
			break;
		DataStructure_MemoryCpy(temp, end->data, dataSize);
		DataStructure_MemoryCpy(end->data, head->data, dataSize);
		DataStructure_MemoryCpy(head->data, temp, dataSize);

		head = head->next;
		end = end->pre;
	}

	DataStructure_MemoryFree(temp);
#endif

	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_removeHeader(BidLinkList list, T buf) {
	if (NULL == buf || BidLinkList_isEmpty(list))
		return FALSE;

	BidLinkList_Node temp = list->head->next;

	list->head->next = temp->next;
	temp->next->pre = list->head;

	DataStructure_MemoryCpy(buf, temp->data, list->dataSize);

	BidLinkList_DeleteNode(temp);

	list->length--;
	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_removeEnd(BidLinkList list, T buf) {
	if (NULL == buf || BidLinkList_isEmpty(list))
		return FALSE;

	BidLinkList_Node temp = list->head->pre;

	list->head->pre = temp->pre;
	temp->pre->next = list->head;

	DataStructure_MemoryCpy(buf, temp->data, list->dataSize);
	BidLinkList_DeleteNode(temp);

	list->length--;
	return TRUE;
}

DataStructure_Warning_Unused
Status BidLinkList_remove(BidLinkList list, int index, T buf) {
	if (NULL == buf)
		return FALSE;

	BidLinkList_Node temp = BidLinkList_findNode(list, index);
	if (NULL == temp)
		return FALSE;

	temp->next->pre = temp->pre;
	temp->pre->next = temp->next;

	DataStructure_MemoryCpy(buf, temp->data, list->dataSize);

	BidLinkList_DeleteNode(temp);

	list->length--;
	return TRUE;
}


